package com.abe.mvpcore;

import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public abstract class BasePresenter<V extends BaseView, M> {
    private Reference<V> mViewRef;//View 接口类型的弱引用
    private Reference mModelRef;//Model 的弱引用

    public void attachView(V view) {
        mViewRef = new WeakReference<>(view);
    }

    protected V getView() {
        return mViewRef.get();
    }

    private boolean isViewAttached() {
        return mViewRef != null && mViewRef.get() != null;
    }

    public void detachView() {
        if (mViewRef != null) {
            mViewRef.clear();
            mViewRef = null;
        }
        if (model != null) {
            model = null;
        }
    }

    //获取Model
    private Object model;

    protected M getModel() {
        return (M) mModelRef.get();
    }

    public BasePresenter() {
        Type genType = getClass().getGenericSuperclass();
        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
        Class<?> modelClass = (Class) params[1];
        try {
            model = modelClass.newInstance();
            mModelRef = new WeakReference<>(model);
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    //监听日志
    protected void onEnd(Object o) {
        if (isViewAttached()) {
            getView().onFinish(o);
        } else {
            showViewAttachedError();
        }
    }

    protected boolean onSuccess(Object data) {
        if (isViewAttached()) {
            if (data == null) {
                showViewDataNullError();
            }
            return data != null;
        } else {
            showViewAttachedError();
            return false;
        }
    }

    protected void onFailure(Object o) {
        if (isViewAttached()) {
            getView().onFailure(o);
        } else {
            showViewAttachedError();
        }
    }

    private void showViewAttachedError() {
        w(this.getClass().getName() + ":MVP_PRESENTER_ERROR_ViewAttached");
    }

    private void showViewDataNullError() {
        w(this.getClass().getSimpleName() + ":MVP_PRESENTER_ERROR_DATA_NULL");
    }

    //控制台输出
    private static void w(String message) {
        System.out.println(message);
    }
}
